#include <my_head.h>
sem_t sem;
typedef struct _Msg
{
    const char *src_file;
    const char *dest_file;
    int offset;
    int cp_len;//总字节
}msg_t;

void *task_func(void *arg){
    msg_t msg = *(msg_t *)arg;//接受参数
    sem_post(&sem);//释放信号量
    int fd_src = open(msg.src_file,O_RDONLY);
    if(-1 == fd_src){
        ERR_LOG("open error");
    }
    int fd_dest = open(msg.dest_file,O_WRONLY);
    if(-1 == fd_dest)
        ERR_LOG("open error");
    lseek(fd_src,msg.offset,SEEK_SET);
    lseek(fd_dest,msg.offset,SEEK_SET);//定位光标

    //执行拷贝
    char buff[20];
    int ret;
    int count = 0;//读取到的字节数
    while(0<(ret = read(fd_src,buff,sizeof(buff)))){
        count+= ret;
        if(count >= msg.cp_len){
            write(fd_dest,buff,msg.cp_len-(count-ret));
            break;
        }
        write(fd_dest,buff,ret);
    }
    close(fd_src);
    close(fd_dest);
}

    //获取源文件大小 并 创建目标文件
int get_srclen_and_creat_dest(const char *src_file,const char *dest_file){
    int fd = 0;
    if(-1 == (fd = open(src_file,O_RDONLY)))
        ERR_LOG("open error");
    int length = lseek(fd,0,SEEK_END);
    close(fd);
    if(-1 == (fd = open(dest_file,O_WRONLY|O_CREAT|O_TRUNC,0664)))
        ERR_LOG("open error");
    close(fd);
    return length;
}
int main(int argc, const char *argv[]){
    if(4 != argc){
        printf("Usage : %s src_file dest_file thread_count\n",argv[0]);
        exit(EXIT_FAILURE);
    }
    sem_init(&sem,0,1);//动态初始化
    int thread_count = atoi(argv[3]);
    pthread_t *tid = (pthread_t *)malloc(sizeof(pthread_t)*thread_count);//根据线程数量分配的空间，存放线程的tid
    if(NULL == tid)
        exit(EXIT_FAILURE);
    int length = get_srclen_and_creat_dest(argv[1],argv[2]);
    msg_t msg;//给每个线程传参
    int one_thread_cp_lenth = length / thread_count;//每个线程的任务量
    int ret;
    for(int i = 0;i < thread_count;i++){
        sem_wait(&sem);//获取信号量开始执行
        msg.src_file = argv[1];
        msg.dest_file = argv[2];
        msg.offset = i*one_thread_cp_lenth;
        if(i<thread_count-1){
            msg.cp_len = one_thread_cp_lenth;
        }else{
            msg.cp_len = length - ((thread_count -1 )*one_thread_cp_lenth);//最后一个线程拷贝剩下的字节
        }
        if(0 != (ret = pthread_create(tid+i,NULL,task_func,&msg))){
            printf("pthread_create error : [%d] [%s]\n",ret,strerror(ret));
            exit(EXIT_FAILURE);
        }
    }

    for(int i = 0;i<thread_count;i++){
        pthread_join(tid[i],NULL);//回收子线程资源
    }
    free(tid);
    sem_destroy(&sem);
    return 0;
}